package org.wheel.plugins.toolkit.sql.render;

import cn.hutool.core.util.StrUtil;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * R2DBC 数字占位符风格：$1 $2 $3 ...
 */
public final class DollarNumberRender implements ParamRenderStrategy {

    private final Map<String, Object> paramMap;
    private final AtomicInteger seq = new AtomicInteger(1);

    public DollarNumberRender(LinkedHashMap<String, Object> paramMap) {
        this.paramMap = paramMap;
    }

    @Override
    public String render(String sql) {
        return StrUtil.replace(sql, ":(\\w+)", m -> {
            String key = m.group(1);
            Object value = paramMap.get(key);

            if(value instanceof Collection<?> col){
                List<String> list = new ArrayList<>();
                // 将参数放入 Map 中，并使用序号作为 key
                paramMap.remove(key);
                for (Object o : col) {
                    // 保证同一 key 多次出现仍用相同序号
                    int index = seq.getAndIncrement();
                    paramMap.put(String.valueOf(index),  o);
                    list.add(java.util.regex.Matcher.quoteReplacement("$" + index));
                }
                return String.join(",", list);
            }else{

                // 保证同一 key 多次出现仍用相同序号
                int index = seq.getAndIncrement();

                // 将参数放入 Map 中，并使用序号作为 key
                paramMap.remove(key);
                paramMap.put(String.valueOf(index),  value);
                // 关键：把 $ 转义成 \$
                return java.util.regex.Matcher.quoteReplacement("$" + index);
            }

        });
    }

    @Override
    public Object getParamObject() {
        // 按 SQL 中出现的顺序返回 List
        return paramMap;
    }

    @Override
    public Map<String, Object> getParamMap() {
        return paramMap;
    }
}